'''
Created on Jul 4, 2011

@author: Martin Vegi Kysel
'''

# add the path of the project to the pythonPath, solves bugs with relative importing
import sys,os,glob
pathname = os.path.dirname(sys.argv[0])
parentPath= os.path.abspath(os.path.join(pathname,'..'))
print 'started in:',parentPath
print 'running',sys.version 
sys.path.append(parentPath)

import Tkinter
import random
from tkFileDialog import askdirectory
import csv, json
from time import gmtime, strftime
from FlexBlock import *



''' ======================== BINARY FLAG ======================
change this according to the test data
False = 4 types of orientations
True = binary, black-white, 0/1 only
'''
binaryFlag = False
'''
====================== NON-SQUARE MATRIX WIDTH =================
change this according to the test data
0 = square matrix- compute the size automatically
N = NxM sized matrix, define the WIDTH, the height is computed
'''
flexTileWidth = 0

'''====================== ENABLE THE CORRECTION OF VALUES =====
false = values are parsed into the dict as found in the csv/json file
true = function CorrectDictValue specifies the procedure
'''
correctValues = True

'''
======================= END OF STATIC DEFINITIONS =============
'''

def getDictFromJSONFile(inputFileName):
    
    #tmp = inputFileName.split("/")
    
    #fileName = tmp[len(tmp)-1]
    #print "reading filename:",fileName
    #splitFileName = fileName.split(".")
    
    #dictIndex = splitFileName[1]
    dictIndex = inputFileName
    theDict = dict()

    file = open(inputFileName, 'r') 
    initialDataFile = file.read() # read initial-data-file
    file.close()
    initialData = json.loads(initialDataFile)
    
    del initialData["totalClicks"]
    
    initialData = dict( [ (int(k), v) for k, v in initialData.items() ] )

    for k, v in initialData.items():
        
        #no JSON for old data correction, prepare the data accordingly

        if not theDict.__contains__(dictIndex):
                    newDictList = []
                    theDict[dictIndex] = newDictList
                    
        # append the angle to the index
        theDict[dictIndex].append(correctDictValue(int(trimAllWhitespace(v["angle"]))))
    
    return theDict


def getDictFromCSVFile(inputFileName):

    reader = csv.reader(open(inputFileName,'rb'), delimiter=',')
    
    # initialize variables
    theDict = dict()
    skipNow = 0
    dictIndex = ""
    
    for row in reader:
        
        
        # for faster searching
        bind = trimAllWhitespace(",".join(row))
        # for nonempty arrays starting with #
        if len(bind)!=0 and bind[0]=="#":
            
            
            # skip all besides Final FlexTile
            if bind.find('Final')!=-1:
                skipNow = 0
                
                # find image NR and repetition NR as colon followers
                # add f for Final
                # use it as current index for the dictionary for later steps
                # should the type of the document change, create random number name
                try:
                    colons = findAll(bind,":")
                    dictIndex = inputFileName+"/"+bind[colons[0]+1]+bind[colons[1]+1]+'f'
                except:
                    print "Document structure has changed. Random number represents the file name"
                    dictIndex = random.random()*1000000
                continue
            else:
                skipNow = 1
        
        if skipNow==1:
            continue
            
        # this may be a subject of change, if the csv structure changes.
        # pass only Final States that match [tile-index#], [angle], [clicks]
        if len(row)!=3:
            continue
        
        # skip header lines
        if bind.find('[')!=-1:
            continue
        
        
        # if the dict entry does not yet exists (and it should not)
        if not theDict.__contains__(dictIndex):
                    newDictList = []
                    theDict[dictIndex] = newDictList
                    
        # append the angle to the index
        theDict[dictIndex].append(correctDictValue(int(trimAllWhitespace(row[1]))))
        #print dictIndex, row[1]
                    
    return theDict

def correctDictValue(x):
    y = int(x+.5)  
    if correctValues:
        if y<4:
            y = y*90
        else:
            if y<45: y=0
            elif y>=315: y=0
            elif 45<=y<135: y=90
            elif 135<=y<225: y=180
            elif 225<=y<315: y=270
    return y
    
    


def processDict(theDict, csvWriter = 0):
    
    for key in sorted(theDict.keys()):
        
        if binaryFlag:
            POSSIBLE_STATES = 2
        else:
            POSSIBLE_STATES = 4
        
        # create array for sum over the states, starting with 0
        # the final result represents the probability P of occurrence
        x = [0.0 for i in range(POSSIBLE_STATES)]
        
        # add the state from the dictionary to the array
        for current in theDict[key]:
            position = 0
            if binaryFlag:
                position = int(current)
            else:
                position = (int(current)+360/POSSIBLE_STATES/2)/(360/POSSIBLE_STATES)
            x[position]+=1
        
        # divide by the overall sum of entries
        x = [i/len(theDict[key]) for i in x]
        
        entropyValue = round(Entropy(x),3)
        symmetryValues = roundArray(getSymmetryValues(theDict[key],binaryFlag,flexTileWidth),3)
        rotationalSymmetries = roundArray(getRotationalSymmetries(theDict[key],binaryFlag, flexTileWidth),3)
        translationalSymmetry = round((1-(entropyValue)/2),3)
        tileMakerSymmetry = round(getTileMakerSymmetry(theDict[key], False,flexTileWidth),3)
        print "Parsed List:", theDict[key]
        print "The Entropy for the flexFile",key,"is",entropyValue
        if not binaryFlag:
            print "Orientation ratio by 90 increment (0,90,180,270)"
        else:
            print "Orientation ratio for 0 and 1"
        printRoundedArray(x)
        print "Translational Symmetry:"
        print "%.3f" % translationalSymmetry
        print "Tile Maker Symmetry:"
        print "%.3f" % tileMakerSymmetry
        print "symmetries (hor, ver, 1dia, 2dia):"
        printRoundedArray(symmetryValues)
        print "rotational symmetries (180, 90):"
        printRoundedArray(rotationalSymmetries)
        print "visualization of the matrix:"
        if binaryFlag:
            drawBWMatrix(theDict[key],flexTileWidth)
        else:
            drawMatrix(theDict[key],flexTileWidth)
        #print theDict[key]
        
        if csvWriter !=0:
            printThese = [key]
            printThese.append(entropyValue)
            printThese.append(tileMakerSymmetry)
            printThese.extend(symmetryValues)
            printThese.extend(rotationalSymmetries)
            printThese.append(translationalSymmetry)
            csvWriter.writerow(printThese)

def readJSONFile(infilename,csvWriter = 0):
    try:
        theDict = dict()

        theDict = getDictFromJSONFile(infilename)
    
        print "\n\n\n\n==========now processing file ",infilename,"========"
        processDict(theDict,csvWriter)
    except():
        # prepared to catch file exceptions... kind of
        pass

def readCSVFile(infilename,csvWriter = 0):
    try:
        theDict = dict()

        theDict = getDictFromCSVFile(infilename)
    
        print "\n\n\n\n==========now processing file ",infilename,"========"
        processDict(theDict,csvWriter)
    except():
        # prepared to catch file exceptions... kind of
        pass

#MAIN
#theDict = getDictFromFile("output/2011_6_29_13_25_52_test.csv")

top = Tkinter.Tk()
indirectory =""
indirectory = askdirectory()

# prevent crashes when no directory is selected
if len(indirectory)==0:
    print 'No directory selected. Exiting.'
    exit(0)   
# batch process all log files
# create a csv output writer
csvTimeString = strftime("%d%b%Y-%H-%M-%S", gmtime())
outputFileName = "analyzedFlexTiles_"+csvTimeString+".csv"
csvFile = open(outputFileName,'wb')
csvWriter = csv.writer(csvFile)
csvHeadings = ["File", "Entropy","Tile Makers", "Horizontal","Vertical","1st Dia","2nd Dia", "180 Rotation", "90 Rotation", "Translational"]
csvWriter.writerow(csvHeadings)

for infile in glob.glob( os.path.join(indirectory, '*.d??F') ):
            readJSONFile(infile,csvWriter)
            
for infile in glob.glob( os.path.join(indirectory, '*.d???F') ):
            readJSONFile(infile,csvWriter)
            
for infile in glob.glob( os.path.join(indirectory, '*.d????F') ):
            readJSONFile(infile,csvWriter)
            
for infile in glob.glob( os.path.join(indirectory, '*.csv') ):
            readCSVFile(infile,csvWriter)

csvFile.close()
exit(0)